//
//
//package com.dxy.yesas2020goals.study.partone.disignpattern.cmdpattern.ftp;
//
//import java.io.BufferedInputStream;
//import java.io.BufferedOutputStream;
//import java.io.BufferedReader;
//import java.io.BufferedWriter;
//import java.io.File;
//import java.io.FileInputStream;
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.InputStreamReader;
//import java.io.OutputStream;
//import java.io.OutputStreamWriter;
//import java.io.PrintStream;
//import java.io.PrintWriter;
//import java.net.Socket;
//import java.util.List;
//
//import com.chnmooc.common.config.SystemConfig;
//import com.chnmooc.common.constants.SyncConstants;
//import com.chnmooc.core.file.OFile;
//import com.chnmooc.core.ftp.SocketPool.ServerSocket2;
//import com.chnmooc.syncftp.model.UFile;
//import com.chnmooc.syncftp.service.facade.IAccessService;
//import com.chnmooc.syncftp.service.facade.ILimiterService;
//import com.twmacinta.util.MD5;
//
///** 数据线程 */
//public class DataThread extends Thread {
////	public static String filesDepot = "/home/FilesDepot/";
//
//	// 通用参数
//	private PrintWriter out = null;
//	private Socket theSocket = null;
//	public boolean isClosed = false;
//
//	// 操作定义
//	private static final int DO_NOOP = 0;
//	private static final int DO_PASV = 1;
//	private static final int DO_PORT = 2;
//	private static final int DO_LIST = 3;
//	private static final int DO_NLST = 4;
//	private static final int DO_RETR = 5;
//	private static final int DO_STOR = 6;
//	private static final int DO_EPSV = 7;
//
//	private int todo = DO_NOOP;
//
//	// PASV，PORT 需要的参数
//	private ServerSocket2 lssock = null;
//	private String ip = null;
//	private int port = 0;
//
//	// LIST，NLST，RETR，STOR 需要的参数
//	ILimiterService theLimiter = null;
//	IAccessService theAccess = null;
//
//	// LIST，NLST
//	String strDir = null;
//	String strFilter = null;
//
//	// RETR，STOR
//	String strPath = null;
//	long restOff = 0;
//	char dataType = 'I';
//
//	// 速度
//	boolean limited = false;
//	int sleeptm = 0;
//	int bufSize = 1024 * 1000;
//	byte buf[] = new byte[bufSize];
//
//	static int serial = 1;
//
//	/**
//	 * 构造函数
//	 *
//	 * @param pw
//	 *            命令线程输出流
//	 */
//	public DataThread(ILimiterService Limiter, PrintWriter pw, ThreadGroup group) {
//		super(group, "DataThread-" + serial++);
//
//		theLimiter = Limiter;
//		theAccess = Limiter.getAccess();
//		out = pw;
//		this.setDaemon(true);
//	}
//
//	/** 被动建立连接 */
//	public void PASV(String localIP) {
//		ip = localIP;
//		todo = DO_PASV;
//		start();
//	}
//
//	public void EPSV(String localIP) {
//		ip = localIP;
//		todo = DO_EPSV;
//		start();
//	}
//
//	/** 主动建立连接 */
//	public void PORT(String param) {
//		param = param.replace(',', ' ');
//		ip = FtpTools.SubStr(param, 1) + "." + FtpTools.SubStr(param, 2) + "." + FtpTools.SubStr(param, 3) + "." + FtpTools.SubStr(param, 4);
//		port = Integer.parseInt(FtpTools.SubStr(param, 5)) * 256 + Integer.parseInt(FtpTools.SubStr(param, 6));
//		todo = DO_PORT;
//		start();
//	}
//
//	public void EPRT(String param) {
//		String[] ps = param.split("\\|");
//		ip = ps[2];
//		port = Integer.parseInt(ps[3]);
//		todo = DO_PORT;
//		start();
//	}
//
//	/** 列目录 */
//	public void LIST(String dir, String filter) {
//		strDir = dir;
//		strFilter = filter;
//		todo = DO_LIST;
//		interrupt();
//	}
//
//	/** 列目录文件名 */
//	public void NLST(String dir, String filter) {
//		strDir = dir;
//		strFilter = filter;
//		todo = DO_NLST;
//		interrupt();
//	}
//
//	public void RETR(String Path, long Off, char Type) {
//		strPath = Path;
//		restOff = Off;
//		dataType = Type;
//		todo = DO_RETR;
//		interrupt();
//	}
//
//	public void STOR(String Path, long Off, char Type) {
//		strPath = Path;
//		restOff = Off;
//		dataType = Type;
//
//		todo = DO_STOR;
//		interrupt();
//	}
//
//	// 线程执行
//	public void run() {
//		int localPort;
//
//		switch (todo) {
//		case DO_PASV:
//			// 创建
//			try {
//				lssock = SocketPool.getServerSocket();
//			} catch (IOException ioe) {
//				out.println("500 Pasv failed.");
//				return;
//			}
//
//			// 返回信息
//			localPort = lssock.getLocalPort();
//			out.println("227 (" + ip.replace('.', ',') + "," + String.valueOf(localPort / 256) + "," + String.valueOf(localPort % 256) + ") Pasv succeeded.");
//
//			// 建立连接
//			try {
//				lssock.setSoTimeout(30000); // 等待30秒
//				theSocket = lssock.accept();
//			} catch (Exception e) {
//				e.printStackTrace();
//				out.println("425 Pasv failed");
//				close();
//				return;
//			}
//			// 停止监听
//			try {
//				lssock.close();
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
//			lssock = null;
//			break;
//
//		case DO_EPSV:
//			// 创建
//			try {
//				lssock = SocketPool.getServerSocket();
//			} catch (IOException ioe) {
//				out.println("500 Pasv failed.");
//				return;
//			}
//
//			// 返回信息
//			localPort = lssock.getLocalPort();
//			out.println("229 Extended Passive mode OK (|||" + String.valueOf(localPort) + "|)");
//
//			// 建立连接
//			try {
//				lssock.setSoTimeout(30000); // 等待30秒
//				theSocket = lssock.accept();
//			} catch (Exception e) {
//				out.println("425 Pasv failed");
//				close();
//				return;
//			}
//			// 停止监听
//			try {
//				lssock.close();
//			} catch (IOException e) {
//			}
//			lssock = null;
//			break;
//
//		case DO_PORT:
//			// 连接
//			try {
//				theSocket = new Socket(ip, port);
//				out.println("200 Port succeeded"); // 成功
//			} catch (IOException e) {
//				System.out.println("PORT Error: " + e);
//				out.println("425 Port failed");
//				close();
//				return;
//			}
//			break;
//
//		default:
//			close();
//			return;
//		}
//
//		// 建立连接成功，等待interrupt
//		try {
//			sleep(30000);
//		} catch (InterruptedException e) {
//		}
//
//		switch (todo) {
//		case DO_LIST:
//			try {
//				out.println("150 Ready to List Directory of \"" + strDir + strFilter + "\"");
//				PrintWriter aout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(theSocket.getOutputStream(), "GB2312")), true);
//
//				// 权限检查
//				if (!theAccess.getAccessPermission(strDir, IAccessService.OPER_LIST).getData()) {
//					aout.close();
//					out.println("226 List Directory of \"" + strDir + "\" not permitted.");
//					break;
//				}
//
////				String strAbsDir = theAccess.getAbsolutePath(strDir);
//
//
//				List<UFile> files = theAccess.getFiles(strDir).getData();
//
//				for (UFile f : files) {
//					if(SyncConstants.FILE_TYPE_DIR.equals(f.getFtype())){
//						aout.println("drwxr-xr-- 1 user user " + FtpTools.right("            " + String.valueOf(f.getFsize()), 12) + " " + FtpTools.getUnixDate(f.getLastModified()) + " " + f.getFname());
//					}else{
//						aout.println("-rwxr-xr-- 1 user user " + FtpTools.right("            " + String.valueOf(f.getFsize()), 12) + " " + FtpTools.getUnixDate(f.getLastModified()) + " " + f.getFname());
//					}
//				}
//
//				ListFilter fltr = null;
//				/*
//				OFile d = new OFile(strAbsDir);
//
//				OFile FileList[];
//				if (strFilter.length() > 0) {
//					fltr = new ListFilter(strFilter);
//					FileList = d.listFiles(fltr);
//				} else
//					FileList = d.listFiles();
//
//				for (int i = 0; i < FileList.length; i++) {
//					OFile f = FileList[i];
//					if (f.isHidden())
//						continue;
//
//					if (f.isDirectory()) {
//						aout.println("drwxr-xr-- 1 user user " + FtpTools.right("            " + String.valueOf(f.length()), 12) + " " + FtpTools.getUnixDate(f.lastModified()) + " " + f.getName());
//					} else {
//						aout.println("-rwxr-xr-- 1 user user " + FtpTools.right("            " + String.valueOf(f.length()), 12) + " " + FtpTools.getUnixDate(f.lastModified()) + " " + f.getName());
//					}
//				}
//				 */
//				aout.print(theAccess.LISTV(strDir, fltr));
//				aout.close();
//
//				out.println("226 List finished.");
//
//			} catch (Exception e) {
//				if (isClosed)
//					out.println("426 List failed.");
//				else
//					out.println("500 List failed.");
//			} finally {
//				try {
//					theSocket.close();
//				} catch (Exception e) {
//				}
//			}
//			break;
//
//		case DO_NLST:
//			try {
//				out.println("150 Ready to NList Directory of \"" + strDir + strFilter + "\"");
//				PrintWriter aout = new PrintWriter(theSocket.getOutputStream(), true);
//
//				// 权限检查
//				if (!theAccess.getAccessPermission(strDir, IAccessService.OPER_LIST).getData()) {
//					aout.close();
//					out.println("226 NList Directory of \"" + strDir + "\" not permitted.");
//					break;
//				}
//
//				String strAbsDir = theAccess.getAbsolutePath(strDir).getData();
//				OFile d = new OFile(strAbsDir);
//				ListFilter fltr = null;
//
//				OFile FileList[];
//				if (strFilter.length() > 0) {
//					fltr = new ListFilter(strFilter);
//					FileList = d.listFiles(fltr);
//				} else
//					FileList = d.listFiles();
//
//				for (int i = 0; i < FileList.length; i++) {
//					if (!FileList[i].isHidden())
//						aout.println(FileList[i].getName());
//				}
//
//				aout.print(theAccess.NLSTV(strDir, fltr));
//				aout.close();
//
//				out.println("226 NList finished.");
//
//			} catch (Exception e) {
//				if (isClosed)
//					out.println("426 NList failed.");
//				else
//					out.println("500 NList failed.");
//			} finally {
//				try {
//					theSocket.close();
//				} catch (Exception e) {
//				}
//				theSocket = null;
//			}
//			break;
//
//		case DO_RETR:
//			try {
//				OutputStream oout = theSocket.getOutputStream();
//
//				// 权限检查
//				if (!theAccess.getAccessPermission(strPath, IAccessService.OPER_DOWNLOAD).getData()) {
//					oout.close();
//					out.println("450 Download \"" + strPath + "\" not permitted.");
//					break;
//				}
//
//				out.println("150 Ready to download.");
//
//				// 不支持文本的 REST
//				if (restOff > 0)
//					dataType = 'I';
//
//				// 速度限制
//				setSpeed(theAccess.getDownloadSpeedLimit(strPath).getData());
//
//				 // 获取真实文件
//				UFile f = theAccess.getFileByPath(strPath).getData();
//				OFile file = null;
//				if(null != f){
//					file = new OFile(theAccess.getOriginalPath(f.getObjectId()).getData());
//				}else{
////				if(!file.exists()) {
//					out.println("550 Download failed.");
//					return;
//				}
//
//				if (dataType == 'I') {
//					// 从文件的输入流
//
//					BufferedInputStream iin = new BufferedInputStream(new FileInputStream(file.getRealFilePath()));
//					// Socket 输出流
//					BufferedOutputStream iout = new BufferedOutputStream(oout);
//
//					// REST
//					if (restOff > 0)
//						iin.skip(restOff);
//
//					byte b[] = buf;
//					int red = -1;
//					while ((red = iin.read(b)) != -1) {
//						iout.write(b, 0, red);
//						// if (limited) sleep(sleeptm); // 速度限制
//					}
//					iout.close();
//					iin.close();
//				} else {
//					// 文件文本输入流
//					BufferedReader ain = new BufferedReader(new InputStreamReader(new FileInputStream(file.getRealFilePath())));
//					// Socket 文本输出流
//					PrintStream aout = new PrintStream(new BufferedOutputStream(oout), true);
//
//					int cntr = 0;
//					String aline = null;
//					while (true) {
//						aline = ain.readLine();
//						if (aline == null) break;
//						aout.print(aline);
//						aout.print("\r\n");
//
//						// 速度限制
//						if (limited) {
//							cntr += aline.length();
//							if (cntr >= bufSize) {
//								cntr -= bufSize;
//								sleep(sleeptm);
//							}
//						}
//					}
//					aout.close();
//					ain.close();
//				}
//
//				out.println("226 Download succeeded.");
//
//			} catch (Exception e) {
//				out.println((isClosed ? 426 : 550) + " Download failed.");
//			} finally {
//				try { theSocket.close(); } catch (Exception e) { }
//				theSocket = null;
//			}
//			break;
//
//		case DO_STOR:
//			try {
//				InputStream oin = theSocket.getInputStream();
//				strDir = strPath.substring(0, strPath.lastIndexOf('/') + 1);
//
//				// 权限检查
//				if (!theAccess.getAccessPermission(strPath, IAccessService.OPER_UPLOAD).getData()) {
//					oin.close();
//					out.println("450 Upload to \"" + strDir + "\" not permitted.");
//					break;
//				}
//
//				boolean limitSpace = theAccess.getSpaceLimit(strDir).getData() > 0;
//				long spaceFree = theAccess.getSpaceFree(strDir).getData();
//				long spaceSumr = 0;
//
//				// 有无空间
//				if (limitSpace && spaceFree <= 0) {
//					oin.close();
//					out.println("450 No space free in Directory of \"" + strDir + "\"");
//					break;
//				}
//
//
//
//				//生成ObjectId
////				String objectId = MD5.calcMD5(strPath + System.currentTimeMillis());
////				String savepath = objectId.replaceAll("(.{3})", "$1/");
//				OFile of = new OFile(strPath);
//				String xpath = strPath.replace(of.getName(), "");
//				String fname = of.getName();
////				String ext = fname.substring(fname.lastIndexOf("."));
//
//				if(theAccess.exists(xpath + fname).getData()){
//					out.println("450 Overwrite an Existing File Not Permitted.");
//					break;
//				}
//
//				String strAbsPath = theAccess.getAbsolutePath(strPath).getData();
//
//				// 生成目录
//				File f = new File(strAbsPath);
//				File parent = f.getParentFile();
//				if (parent != null && !parent.exists()) {
//					parent.mkdirs();
//				}
//
//				FileOutputStream oout = null;
//
//				// REST
//				if (restOff > 0) {
//					dataType = 'I';
//					//if (f.exists() && f.length() == restOff)
//						oout = new FileOutputStream(strAbsPath + "", true);
//					/*else {
//						// 只能从断点继续
//						oin.close();
//						out.println("450-Restart uploading Error");
//						out.println("450 Multi-line Upload NOT supported.");
//						break;
//					}*/
//				} else {
//					if (!f.exists() || theAccess.getAccessPermission(strPath, IAccessService.OPER_DELETE).getData())
//						oout = new FileOutputStream(strAbsPath + "");
//					else {
//						// 不可以覆盖现有文件
//						oin.close();
//						out.println("450 Overwrite an Existing File Not Permitted.");
//						break;
//					}
//				}
//
//				out.println("150 Ready to upload.");
//
//				// 速度限制
//				setSpeed(theAccess.getUploadSpeedLimit(strPath).getData());
//
//				try // 为了空间占用问题而try,finally
//				{
//					if (dataType == 'I') {
//						// 从文件的输入流
//						BufferedInputStream iin = new BufferedInputStream(oin);
//						// Socket 输出流
//						BufferedOutputStream iout = new BufferedOutputStream(oout);
//
//						byte b[] = buf;
//						int red = -1;
//						while ((red = iin.read(b)) != -1) {
//							iout.write(b, 0, red);
//
//							// 速度限制
//							if (limited)
//								sleep(sleeptm);
//
//							// 空间限制
//							if (limitSpace) {
//								spaceSumr += red;
//								if (spaceSumr > spaceFree) {
//									iout.close();
//									oout.close();
//									f.delete();
//									out.println("550 No Enough Space.");
//									throw new Exception("No enough space.");
//								}
//							}
//						}
//						iout.close();
//						iin.close();
//					} else {
//						// 文件文本输入流
//						BufferedReader ain = new BufferedReader(new InputStreamReader(oin));
//						// Socket 文本输出流
//						PrintStream aout = new PrintStream(new BufferedOutputStream(oout), true);
//
//						int cntr = 0;
//						String aline = null;
//						while (true) {
//							aline = ain.readLine();
//
//							if (aline == null)
//								break;
//							aout.print(aline);
//							aout.print("\r\n");
//
//							// 速度限制
//							if (limited) {
//								cntr += aline.length();
//								if (cntr >= bufSize) {
//									cntr -= bufSize;
//									sleep(sleeptm);
//								}
//							}
//							// 空间限制
//							if (limitSpace) {
//								spaceSumr += aline.length();
//								if (spaceSumr > spaceFree) {
//									aout.close();
//									oout.close();
//									f.delete();
//									out.println("550 No Enough Space.");
//									throw new Exception("No enough space.");
//								}
//							}
//						}
//						aout.close();
//						ain.close();
//					}
//
//					// 上传成功修改文件名 删除原文件
////					if (f.isFile() && f.exists()) {
////						f.delete();
////					}
//
//
//					// 优化存储
//					OFile oFile = new OFile(strAbsPath + "");
//					if(oFile.exists()){
//						String filemd5 = MD5.asHex(MD5.getHash(oFile));
//						theAccess.createFile(strPath,filemd5, f);
//						oFile.save(SystemConfig.filesDepot);
//	//					oFile.renameTo(f);
//						System.out.println();
//					}
//
//				} finally { // 空间变化计算
//					if (f.exists())
//						theAccess.setUseSpace(strDir, f.length() - restOff);
//					else
//						theAccess.setUseSpace(strDir, -restOff);
//				}
//
//				out.println("226 Upload succeeded.");
//
//			} catch (Exception e) {
//				e.printStackTrace();
//				if (isClosed)
//					out.println("426 Upload failed.");
//				else
//					out.println("550 Upload failed.");
//			} finally {
//				try {
//					theSocket.close();
//				} catch (Exception e) {
//					e.printStackTrace();
//				}
//				theSocket = null;
//			}
//			break;
//
//		default:
//			out.println("500 Error");
//		case DO_NOOP:
//			System.out.println("One DataThread Done Nothing.");
//			break;
//		}
//
//		// 传输结束
//		close();
//	}
//
//	/** 关闭：清除工作，断开引用 */
//	public void close() {
//		isClosed = true;
//
//		// 中断工作
//		todo = DO_NOOP;
//		interrupt();
//
//		// 强行关闭
//		if (lssock != null) {
//			try {
//				lssock.close();
//			} catch (IOException e) {
//			}
//		}
//
//		// 强行关闭数据连接
//		if (theSocket != null) {
//			try {
//				theSocket.close();
//			} catch (IOException e) {
//			}
//		}
//	}
//
//	/** 设定文件传输速度（单位：字节） */
//	public void setSpeed(long speed) {
//		limited = (0 < speed) && (speed <= 500 * 1024);
//		bufSize = 10240;
//		if (limited) {
//			if (speed < 1024) // 最低速度1K
//				speed = 1024;
//			bufSize = (int) (speed / 1024 / 10 * 1024) + 1024;
//			sleeptm = (int) (bufSize * 1000.0 / speed);
//		}
//		buf = new byte[bufSize];
//		// bufChanged = true;
//	}
//}
